package com.zhixianggou.caibaobox.user.shiro.realms;

import com.zhixianggou.caibaobox.user.dao.UserMapper;
import com.zhixianggou.caibaobox.user.dao.UserMapper;
import com.zhixianggou.caibaobox.user.entities.User;
import com.zhixianggou.caibaobox.user.shiro.ShiroUser;
import jakarta.annotation.Resource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * Created by bxl on 2015/10/30.
 */
//@Log4j
public class ShiroUserRealm extends AuthorizingRealm {

    private Logger logger = LogManager.getLogger(ShiroUserRealm.class);

//    @Resource
//    private SellerMapper sellerMapper;

    @Resource
    UserMapper userMapper;
    /**
     * 授权
     *
     * @param principals principals
     * @return AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        return authorizationInfo;
    }

    /**
     * 必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return true;
    }

    /**
     * 认证
     *
     * @param authcToken token
     * @return AuthenticationInfo
     * @throws AuthenticationException AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {


        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String userName = token.getUsername();
        ShiroUser shiroUser = new ShiroUser();
        User user = userMapper.selectByAccount(userName);
        if (user == null) {
            throw new UnknownAccountException();
        }
        if (user.getIsDel() == 1) {
            throw new DisabledAccountException();
        }

        shiroUser.setUserId(user.getId());
        shiroUser.setUsername(user.getAccount());
        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(shiroUser, user.getLoginPwd(), getName());
        return authcInfo;
    }

    public void clearCachedAuthorizationInfo(User principal) {
//         log.debug("name=" + getName());
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }


    /**
     * 传入用户名，清除shiro缓存中的用户
     *
     * @param account 用户名
     */
    public void clearCachedAuthorizationInfo(String account) {
//        log.debug("name=" + getName());
        SimplePrincipalCollection principals = new SimplePrincipalCollection(account, getName());
        clearCachedAuthorizationInfo(principals);
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            Set<Object> ch = cache.keys();
            for (Object o : ch) {
                SimplePrincipalCollection simplePrincipalCollection = (SimplePrincipalCollection) o;
                AuthorizationInfo info = cache.get(o);

                //              log.debug((o.equals(principals)) + "=" + o.getClass());
                User user = (User) simplePrincipalCollection.getPrimaryPrincipal();
                if (user.getAccount().equals(account)) {
                    cache.remove(o);

                }
                //  log.debug(o + "====>" + info);
            }
            cache.remove(account);
            //  log.debug("remove--->" + principals);
            ch = cache.keys();
            for (Object o : ch) {
                AuthorizationInfo info = cache.get(o);
                //  log.debug(o + "====>" + info);
            }
        }
    }


//    @Override
//    public String getName() {
//        return LoginType.USER_PASSWORD.toString();
//    }


    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }

}
